home *** CD-ROM | disk | FTP | other *** search
- PROGRAM GAUSS
- C
- C FORTRAN-77 PROGRAM TO APPROXIMATE DEFINITE INTEGRALS. VERSION: 4-14-86
- C
- C DAVID M. SMITH
- C MATHEMATICS DEPARTMENT
- C LOYOLA MARYMOUNT UNIVERSITY
- C LOS ANGELES, CA 90045
- C
- C
- IMPLICIT DOUBLE PRECISION (A-H,O-Z)
- DIMENSION TABLE(20)
- C
- C UNIT NUMBERS: KW - SCREEN OUTPUT
- C KR - KEYBOARD INPUT
- C KF - OUTPUT TO FILE 'GAUSSQ.OUT'
- C
- KW = 6
- KR = 5
- KF = 8
- OPEN(KF,FILE='GAUSSQ.OUT',STATUS='NEW')
- C
- C FORTRAN-77 COMPILERS ALLOW THESE 5 INPUT VALUES TO BE
- C ENTERED IN FREE FORMAT. I.E., TO ENTER NFCT = 2 TYPE THE
- C 2 IN COLUMN 1 AND THEN TYPE CARRIAGE RETURN. TO ENTER
- C A = 1 TYPE 1. OR 1.0 THEN RETURN. THE DECIMAL POINT
- C SHOULD BE TYPED FOR THE REAL VALUES (A AND B).
- C
- C MOST FORTRAN-66 COMPILERS WHICH SUPPORT IF-THEN-ELSE
- C REQUIRE THAT THE INTEGERS BE TYPED RIGHT-JUSTIFIED,
- C SO THAT TO ENTER NFCT = 2 TYPE 4 BLANKS AND THEN THE 2
- C IN COLUMN 5.
- C
- 110 WRITE (KW,120)
- 120 FORMAT(/' Enter (1 item per line): NFCT / KL / IOFLAG / A / B.'
- * /7X,'(Format for NFCT,KL,IOFLAG is I5, for A,B is F25.0.'/
- * /' Integrate function NFCT from A to B (NFCT=0 to quit)',
- * /' There will be KL lines in the Gauss',
- * ' column of the table.'/
- * ' IOFLAG = 1 causes the output to be saved in file',
- * ' GAUSSQ.OUT.'/)
- C
- READ (KR,130) NFCT
- 130 FORMAT(I5)
- IF (NFCT.EQ.0) STOP
- READ (KR,140) KL,IOFLAG,A,B
- 140 FORMAT(I5/I5/F25.0/F25.0)
- C
- IF (NFCT.LE.0) STOP
- C
- KPRT = 1
- IF (IOFLAG.EQ.1) KPRT = 2
- CALL GAUSSQ(A,B,NFCT,KL,TABLE,KPRT,KF,KW)
- DO 170 J = 1, 20
- WRITE (KW,150)
- 150 FORMAT(/' ENTER 1 FOR THE NEXT AITKEN COLUMN, 0 TO QUIT.',
- * ' (I1)')
- READ (KR,160) KOPT
- 160 FORMAT(I1)
- IF (KOPT.NE.1) GO TO 110
- CALL AITKEN(TABLE,KL,KPRT,KF,KW)
- KL = KL - 2
- IF (KL.LT.3) GO TO 110
- 170 CONTINUE
- GO TO 110
- C
- END
- SUBROUTINE GAUSSQ(A,B,NFCT,KL,TABLE,KPRT,KF,KW)
- IMPLICIT DOUBLE PRECISION (A-H,O-Z)
- C DAVID M. SMITH 4-14-86
- C
- C ITERATIVE GAUSS QUADRATURE. FUNCTION NUMBER NFCT IS INTEGRATED FROM
- C A TO B PRODUCING KL LINES IN TABLE USING
- C 1, 2, 4, 8, 16, ..., 2**(KL-1) SUBINTERVALS.
- C
- C IF KPRT IS 1 THE TABLE IS WRITTEN ON UNIT KW.
- C IF KPRT IS 2 THE TABLE IS ALSO WRITTEN ON UNIT KF.
- C
- C IN THE TABLE WHICH IS WRITTEN:
- C
- C N IS THE NUMBER OF SUBINTERVALS USED,
- C GAUSS IS THE GAUSS QUADRATURE APPROXIMATION TO THE INTEGRAL,
- C TOTAL NF IS THE TOTAL NUMBER OF FUNCTION EVALUATIONS DONE SO FAR,
- C EST S.D. IS A CONSERVATIVE ESTIMATE OF THE NUMBER OF SIGNIFICANT
- C DIGITS WHICH ARE CORRECT IN THAT LINE
- C
- C THE EXTERNAL FUNCTION CALLED IS F(X,NFCT) FOR THE FUNCTION BEING
- C INTEGRATED.
- C
- DIMENSION TABLE(20)
- C
- C SET EPS TO THE SIZE OF THE ROUNDING ERRORS FOR A GIVEN
- C MACHINE. EPS = 1.0E-7 FOR 32 BIT MACHINES (SINGLE
- C PRECISION) OR 1.0E-16 (DOUBLE PRECISION).
- C
- EPS = 1.0E-16
- C
- C CHECK FOR ERRORS.
- C
- IF (KL.LT.1) THEN
- WRITE (KW,110) KL
- 110 FORMAT(/' ERROR IN GAUSSQ. KL=',I5,'. IT SHOULD BE AT ',
- * 'LEAST 1.')
- DO 120 J = 1, 20
- 120 TABLE(J) = -3.1E+31
- RETURN
- ENDIF
- C
- C DO GAUSS QUADRATURE FOR THE INTEGRAL OF F(X) FROM A TO B.
- C
- NLINES = KL
- SQRT3 = DSQRT(3.0D0)
- NSUBS = 1
- NFUNCT = 0
- C
- IF (KPRT.GE.1) THEN
- WRITE (KW,130) NFCT,NLINES
- IF (KPRT.GE.2) WRITE (KF,130) NFCT,NLINES
- 130 FORMAT(/' GAUSS INTEGRATION OF FUNCTION ',I3,'. THERE',
- * ' ARE',I3,' LINES IN THE TABLE.')
- WRITE (KW,140) A,B
- IF (KPRT.GE.2) WRITE (KF,140) A,B
- 140 FORMAT(/' THE LIMITS OF INTEGRATION ARE:'/3X,D23.16,
- * ' TO ',D23.16/)
- ENDIF
- C
- DO 180 JLINE = 1, NLINES
- C
- C THE KTH SUBINTERVAL IS (AK,BK). THE GAUSS APPROXIMATION
- C FOR THE INTEGRAL IS: XH*(F(XM-XR) + F(XM+XR)), WHERE
- C XH = (BK-AK)/2, XM = (AK+BK)/2, XR = XH/(2*SQRT(3)),
- C AK = A + (K-1)*(B-A)/NSUBS, BK = A + K*(B-A)/NSUBS.
- C
- XH = (B-A)/NSUBS
- XH2 = XH/2.0
- XR = XH2/SQRT3
- START1 = A - XH2 - XR
- START2 = A - XH2 + XR
- SUM = 0.0
- C
- DO 150 K = 1, NSUBS
- C
- 150 SUM = SUM + F(START1+K*XH,NFCT) + F(START2+K*XH,NFCT)
- C
- SUM = SUM*XH2
- C
- NFUNCT = NFUNCT + 2*NSUBS
- IF (KPRT.GE.1) THEN
- IF (JLINE.LE.1) THEN
- WRITE (KW,160) NSUBS,SUM,NFUNCT
- IF (KPRT.GE.2) WRITE (KF,160) NSUBS,SUM,NFUNCT
- 160 FORMAT(' N =',I6,' GAUSS=',D23.16,' TOTAL NF=',I5)
- ELSE
- RELERR = EPS
- IF (SUM.NE.0.0) RELERR = DABS(TABLE(JLINE-1)-SUM)
- * / DABS(SUM)
- IF (SUM.EQ.0.0 .AND. TABLE(JLINE-1).NE.0.0) RELERR =
- * DABS(TABLE(JLINE-1)-SUM) / DABS(TABLE(JLINE-1))
- IF (RELERR.LE.0.0) RELERR = EPS
- NUMSD = -DLOG10(RELERR)
- IF (NUMSD.LT.0) NUMSD = 0
- WRITE (KW,170) NSUBS,SUM,NFUNCT,NUMSD
- IF (KPRT.GE.2) WRITE (KF,170) NSUBS,SUM,NFUNCT,NUMSD
- 170 FORMAT(' N =',I6,' GAUSS=',D23.16,' TOTAL NF=',I5,
- * ' EST S.D.=',I3)
- ENDIF
- ENDIF
- C
- NSUBS = 2*NSUBS
- TABLE(JLINE) = SUM
- 180 CONTINUE
- C
- RETURN
- END
- SUBROUTINE AITKEN(TABLE,KL,KPRT,KF,KW)
- IMPLICIT DOUBLE PRECISION (A-H,O-Z)
- C DAVID M. SMITH 4-14-86
- C
- C AITKEN EXTRAPOLATION. THE VALUES TABLE(1) TO TABLE(KL) ARE USED FOR
- C THE EXTRAPOLATION AND THE RESULTS ARE RETURNED IN TABLE(1) TO
- C TABLE(KL-2). KL MUST BE AT LEAST 3.
- C
- C IF KPRT IS 1 THEN THE KL-2 VALUES ARE WRITTEN ON UNIT KW.
- C IF KPRT IS 2 THE TABLE IS ALSO WRITTEN ON UNIT KF.
- C
- C IN THE TABLE WHICH IS WRITTEN:
- C
- C LINE IS THE LINE NUMBER,
- C AITKEN IS THE AITKEN EXTRAPOLATION APPROXIMATION TO THE INTEGRAL,
- C USING 3 VALUES FROM THE PREVIOUS COLUMN. FOR EXAMPLE,
- C LINE 1 OF AN AITKEN COLUMN USES LINES 1-3 OF THE PREVIOUS
- C COLUMN, LINE 4 USES LINES 4-6, ETC.
- C EST S.D. IS A CONSERVATIVE ESTIMATE OF THE NUMBER OF SIGNIFICANT
- C DIGITS WHICH ARE CORRECT IN THAT LINE
- C
- DIMENSION TABLE(20)
- C
- C SET EPS TO THE SIZE OF THE ROUNDING ERRORS FOR A GIVEN
- C MACHINE. EPS = 1.0E-7 FOR 32 BIT MACHINES (SINGLE
- C PRECISION) OR 1.0E-16 (DOUBLE PRECISION).
- C
- EPS = 1.0E-16
- C
- IF (KL.LT.3) THEN
- WRITE (KW,110) KL
- 110 FORMAT(//' ERROR IN AITKEN. KL=',I5,' IS LESS THAN 3.'/)
- RETURN
- ENDIF
- C
- IF (KPRT.GE.1) THEN
- KLM2 = KL - 2
- WRITE (KW,120) KLM2
- IF (KPRT.GE.2) THEN
- IF (KLM2.GT.1) THEN
- WRITE (KF,120) KLM2
- 120 FORMAT(/' AITKEN COLUMN.',I4,' ENTRIES.'/)
- ELSE
- WRITE (KF,130) KLM2
- 130 FORMAT(/' AITKEN COLUMN.',I4,' ENTRY.'/)
- ENDIF
- ENDIF
- ENDIF
- C
- KLM1 = KL - 1
- DO 160 JLINE = 2, KLM1
- TOP = (TABLE(JLINE+1) - TABLE(JLINE))**2
- BOT = TABLE(JLINE+1) - 2.0*TABLE(JLINE) + TABLE(JLINE-1)
- C
- IF (BOT.EQ.0.0) THEN
- TABLE(JLINE-1) = TABLE(JLINE+1)
- ELSE
- TABLE(JLINE-1) = TABLE(JLINE+1) - TOP/BOT
- ENDIF
- C
- IF (KPRT.GE.1) THEN
- JLM1 = JLINE - 1
- IF (JLINE.LE.2) THEN
- WRITE (KW,140) JLM1,TABLE(JLM1)
- IF (KPRT.GE.2) WRITE (KF,140) JLM1,TABLE(JLM1)
- 140 FORMAT(' LINE',I3,' AITKEN=',D23.16)
- ELSE
- RELERR = EPS
- IF (TABLE(JLM1).NE.0.0) RELERR = DABS(TABLE(JLM1-1) -
- * TABLE(JLM1))/DABS(TABLE(JLM1))
- IF (TABLE(JLM1).EQ.0.0 .AND. TABLE(JLM1-1).NE.0.0)
- * RELERR = DABS(TABLE(JLM1-1)-TABLE(JLM1)) /
- * DABS(TABLE(JLM1-1))
- IF (RELERR.LE.0.0) RELERR = EPS
- NUMSD = -DLOG10(RELERR)
- IF (NUMSD.LT.0) NUMSD = 0
- WRITE (KW,150) JLM1,TABLE(JLM1),NUMSD
- IF (KPRT.GE.2) WRITE (KF,150) JLM1,TABLE(JLM1),NUMSD
- 150 FORMAT(' LINE',I3,' AITKEN=',D23.16,
- * ' EST S.D.=',I3)
- ENDIF
- ENDIF
- C
- 160 CONTINUE
- C
- RETURN
- END
- FUNCTION F(X,NFCT)
- C
- C COMPUTE F(X) FOR FUNCTION NUMBER NFCT.
- C THIS CALLING SEQUENCE ALLOWS MANY DIFFERENT FUNCTIONS TO BE USED
- C EASILY DURING ONE RUN.
- C
- IMPLICIT DOUBLE PRECISION (A-H,O-Z)
- C
- C IF NFCT IS OUTSIDE THE RANGE OF CURRENTLY DEFINED
- C FUNCTIONS THEN RETURN THE FUNCTION VALUE -9.9E+20.
- C ANY OUTPUT TABLES CONSISTING ENTIRELY OF THIS VALUE ARE
- C ALMOST CERTAINLY CAUSED BY SENDING THE WRONG VALUE OF
- C NFCT.
- C
- F = -9.9E+20
- IF (NFCT.LT.1 .OR. NFCT.GT.6) RETURN
- C
- GO TO (1,2,3,4,5,6),NFCT
- C
- 1 F = DSQRT(DEXP(X)-1.0D0)/DSIN(X)
- RETURN
- C
- 2 F = DABS(X-0.3)**0.33333
- RETURN
- C
- C THIS FUNCTION IS 1/(X**4 + X**2 + 1)
- C THE FORM USED BELOW EXECUTES FASTER.
- C
- 3 F = 1.0/((X*X+1)*X*X + 1)
- RETURN
- C
- 4 T = X*X + 1.0
- F = T/(T*X*X + 1)
- RETURN
- C
- 5 F = DSQRT(X)/(X - 1.0) - 1.0/DLOG(X)
- RETURN
- C
- 6 F = 2.0*X*X/((X-1.0)*(X+1.0)) - X/DLOG(X)
- RETURN
- C
- END